﻿using System;
using System.Text;
using Ayatta.Contract.Component;
using Dapper;
using System.Data;
using System.Linq;
using System.Configuration;
using System.Data.SqlClient;
using Ayatta.Contract.Domain;
using System.Collections.Generic;

namespace Ayatta.Service
{
    public abstract class ServiceBase
    {
        #region ConnectionManager


        private static readonly IDictionary<string, string> SqlConnectionStringDic = new Dictionary<string, string>();

        protected internal IDbConnection GetConnection(string name)
        {
            string connectionstring;
            if (SqlConnectionStringDic.ContainsKey(name))
            {
                connectionstring = SqlConnectionStringDic[name];
            }
            else
            {
                connectionstring = ConfigurationManager.ConnectionStrings[name].ConnectionString;
                SqlConnectionStringDic[name] = connectionstring;
            }
            return new SqlConnection(connectionstring);
        }

        #endregion

        #region

        //        protected internal SqlBuilder.Template GetPagedTemplate(SqlBuilder builder, string master, string sub)
        //        {
        //            var sb = new StringBuilder();
        //            sb.Append("select count(0) from /**table**/ /**where**/ ;with [temp.talbe] as (select row_number() over(/**orderby**/) as rowid,id from /**table**/ (nolock) /**where**/)");

        //            var sql = @"select count(0) from /**table**/ /**where**/ ;
        //        with [temp.talbe] as (select row_number() over(/**orderby**/) as rowid,id from /**table**/ (nolock) /**where**/)
        //        select * from [Order.item] a
        //left join [temp.table] b on a.OrderId=b.Id
        //INNER JOIN [Order] c ON b.ID = c.ID
        //WHERE ROWNUM BETWEEN @START_ROW AND @START_ROW + @MAX_ROWS - 1
        //order by c.CreatedOn desc";
        //            //var sb = new SqlBuilder().

        //        } 

        protected internal static IEnumerable<T> Query<T>(IDbConnection connection, SqlBuilder.Template template)
        {

            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }
            return connection.Query<T>(template);

        }

        protected internal static long InsertReturnLastLongId<T>(T o, IDbConnection connection,SqlBuilder.Template template,IDbTransaction dbTransaction = null)where T : IEntity<long>
        {
            var sql = template.RawSql + "SELECT SCOPE_IDENTITY();";

            connection.EnsureOpen();
            var data = connection.Query<decimal>(sql, template.Parameters, dbTransaction).First();
            return (long)data;
        }

        protected internal static int InsertReturnLastId<T>(T o, IDbConnection connection, SqlBuilder.Template template,
                                                            IDbTransaction dbTransaction = null) where T : IEntity<int>
        {
            var sql = template.RawSql + "SELECT SCOPE_IDENTITY();";

            connection.EnsureOpen();
            var data = connection.Query<decimal>(sql, template.Parameters, dbTransaction).First();
            return (int)data;
        }
        protected internal static int Execute(IDbConnection connection, string spName, DynamicParameters param)
        {
            connection.EnsureOpen();
            return connection.Execute(spName, param, commandType: CommandType.StoredProcedure);
        }
        protected internal static int Execute(IDbConnection connection, SqlBuilder.Template template,
                                              IDbTransaction dbTransaction = null)
        {
            connection.EnsureOpen();
            return connection.Execute(template, dbTransaction);
        }

        protected internal static int BatchInsert<T>(IDbConnection connection, string sql, IEnumerable<T> values,
                                                     IDbTransaction dbTransaction = null)
        {
            connection.EnsureOpen();
            return connection.BatchInsert(sql, values, dbTransaction);
        }

        #endregion

    }

    #region

    internal static class ConnectionName
    {
        internal static readonly string Base = "SilenthinkBase";
        internal static readonly string Main = "SilenthinkMain";
        internal static readonly string Extra = "SilenthinkExtra";
        internal static readonly string Store = "SilenthinkStore";
        internal static readonly string Order = "SilenthinkOrder";
        internal static readonly string Game = "SilenthinkGame";
        internal static readonly string Passport = "SilenthinkPassport";
        internal static readonly string Payment = "SilenthinkPayment";

        internal static readonly string Auction = "SilenthinkAuction";
        internal static readonly string Log = "SilenthinkLog";

    }

    #endregion

    internal static class Database
    {
        internal static class Passport
        {
            internal static class Table
            {
                internal static readonly string User = "[User]";
                internal static readonly string UserExtra = "[User.Extra]";
                internal static readonly string UserProfile = "[User.Profile]";
                internal static readonly string UserAddress = "[User.Address]";
                internal static readonly string UserInvoice = "[User.Invoice]";
                internal static readonly string OAuthConfig = "[OAuthConfig]";
            }
        }

        internal static class Payment
        {
            internal static class Table
            {
                internal static readonly string UserAccount = "[User.Account]";
                internal static readonly string UserTrade = "[User.Trade]";
                internal static readonly string UserRecharge = "[User.Recharge]";

                internal static readonly string RechargePackage = "[Recharge.Package]";
                internal static readonly string RechargePackageRequirement = "[Recharge.Package.Requirement]";

                internal static readonly string PayTrade = "[Pay.Trade]";

                internal static readonly string UserIntegral = "[User.Currency.Integral]";
                internal static readonly string PaymentBank = "[Payment.Bank]";
                internal static readonly string PaymentEBank = "[Payment.EBank]";
                internal static readonly string PaymentPlatform = "[Payment.Platform]";
            }

        }
        internal static class Auction
        {
            internal static class Table
            {
                internal static readonly string Auction = "[Auction]";
                internal static readonly string Bidding = "[Auction.Bidding]";
                internal static readonly string AuctionOrder = "[Auction.Order]";
                internal static readonly string AuctionShare = "[Auction.Share]";
                internal static readonly string AuctionRobot = "[Auction.Robot]";
            }
        }

        internal static class Base
        {
            internal static class Table
            {
                internal static readonly string Faq = "[Faq]";
                internal static readonly string Area = "[Area]";
                internal static readonly string EmailAccount = "[Email.Account]";
                internal static readonly string EmailTemplate = "[Email.Template]";
                internal static readonly string EmailQueue = "[Email.Queue]";
                internal static readonly string LogisticsCompany = "[Logistics.Company]";
                internal static readonly string Slide = "[Slide]";
                internal static readonly string SlideCategory = "[Slide.Category]";
            }

        }
        internal static class Order
        {
            internal static class Table
            {
                internal static readonly string Order = "[Order]";
                internal static readonly string OrderExtra = "[Order.Extra]";
                internal static readonly string OrderItem = "[Order.Item]";
                internal static readonly string OrderExchangeDetail = "[Order.Exchange.Detail]";

                internal static readonly string OrderNote = "[Order.Note]";
                internal static readonly string Shipping = "[Shipping]";
                internal static readonly string ShippingExtra = "[ShippingExtra]";

                internal static readonly string Refund = "[Refund]";
            }

        }
        internal static class Game
        {
            internal static class Table
            {
                internal static readonly string Game = "[Game]";
                internal static readonly string GameUser = "[Game.User]";
                internal static readonly string GameServer = "[Game.Server]";
                internal static readonly string GameArticle = "[Game.Article]";
                internal static readonly string GameTrial = "[Game.Trial]";
                internal static readonly string GameTrialHistory = "[Game.Trial.History]";

                internal static readonly string GameNoviceCard = "[Game.Novice.Card]";

            }
        }

        internal static class Store
        {
            internal static class Table
            {
                internal static readonly string ProductCategory = "[ProductCategory]";

                internal static readonly string Product = "[Product]";

                internal static readonly string ProductItem = "[Product.Item]";
                internal static readonly string ProductItemSku = "[Product.Item.Sku]";

                internal static readonly string ProductExtra = "[ProductExtra]";
                internal static readonly string ProductVariant = "[ProductVariant]";

                internal static readonly string ProductAttribute = "[ProductAttribute]";

                internal static readonly string ProductAttributeName = "[ProductAttributeName]";
                internal static readonly string ProductAttributeValue = "[ProductAttributeValue]";

                internal static readonly string Discount = "[Discount]";
                internal static readonly string DiscountRequirement = "[Discount.Requirement]";
                internal static readonly string DiscountProductCategoryMapping = "[DiscountProductCategoryMapping]";
                internal static readonly string DiscountItemMap = "[Discount.Item.Map]";
                internal static readonly string DiscountUsageHistory = "[Discount.UsageHistory]";

                internal static readonly string ProductAdvisory = "[ProductAdvisory]";
                internal static readonly string ProductReview = "[ProductReview]";



            }
        }

        internal static class Extra
        {
            internal static class Table
            {
                internal static readonly string RegisterLog = "[Register.Log]";
                internal static readonly string VerificationSms = "[Verification.Sms]";
                internal static readonly string VerificationEmail = "[Verification.Email]";

            }

        }

        internal static class Log
        {
            internal static class Table
            {
                internal static readonly string AppException = "[App.Exception]";
            }

        }
    }
}